#pragma once
#include <ostream>

using namespace std;

// Interface for classes that store output values.
template<class TVal> class ISink {
    public:
        virtual ~ISink() {}
        virtual void Process(const TVal val) = 0;
		virtual long ProcessedCount() = 0;
};

// Sink that prints to an ostream
template<class TVal> class Printer : public ISink<TVal> {
	private:
		ostream& _out;
		long _count;

	public:
		Printer(ostream& out);
		virtual void Process(const TVal val);
		virtual long ProcessedCount();
};


// *** *** TEMPLATE IMPLEMENTATIONS *** *** //

template<class TVal> Printer<TVal>::Printer(ostream& out) : _out(out) {
	if(!_out.good() || _out.eof())
		throw "Bad output stream.";
	_count = 0;
}

template<class TVal> void Printer<TVal>::Process(const TVal val) {
// TODO: build a buffering mechanism around this, as ostreams are not that quick...
#ifdef SINK_DEBUG
	_out << _count << ": " << endl;
#endif
	_out << val << endl;
	_count++;
}

template<class TVal> long Printer<TVal>::ProcessedCount() {
	return _count;
}